/*
 * The JAnalytics Library provides a Java API to the Google Analytics service.
 * Copyright (C) 2007 Ansir Development Limited (http://www.ansir.ca)
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

package ca.ansir.analytics.servlet;

import java.io.IOException;
import java.util.Calendar;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ca.ansir.analytics.reports.FilterModes;
import ca.ansir.analytics.reports.JAnalytics;
import ca.ansir.analytics.reports.JAnalyticsException;
import ca.ansir.analytics.reports.ReportTypes;
import ca.ansir.analytics.util.Utilities;

/**
 * The <code>ReportServlet</code> provides access to Google Analytics XML
 * reports. There are a number of required attributes that must be available as
 * either get, or post parameter, or session as session attributes. The
 * <b>required</b> parameters/attributes are:
 * <ul>
 * <li><code>JAnalytics.EMAIL_ATTRIBUTE_NAME</code> ("Email") which must be a
 * valid Google Analytics account email.</li>
 * <li><code>JAnalytics.PASSWORD_ATTRIBUTE_NAME</code> ("Passwd") which must
 * be a valid Google Analytics account password.</li>
 * <li><code>JAnalytics.START_DATE_ATTRIBUTE_NAME</code> ("bd") which must be
 * a date in the form given by <code>JAnalytics.DEFAULT_USER_DATE_FORMAT</code>
 * ("dd/MM/yyyy") or you may include the optional parameter
 * <code>JAnalytics.DATE_FORMAT_ATTRIBUTE_NAME</code> which is discussed in
 * the next section.</li>
 * <li><code>JAnalytics.END_DATE_ATTRIBUTE_NAME</code> ("ed") and has the
 * same formatting as the start date above.</li>
 * </ul>
 * <p>
 * The optional parameters are:
 * </p>
 * <ul>
 * <li><code>JAnalytics.REPORT_ID_ATTRIBUTE_NAME</code> ("rid") and if not
 * supplied the first report id will be used and obtained from the
 * <code>JAnalytics</code> objects <code>getReportIds</code> method.</li>
 * <li><code>JAnalytics.REPORT_TYPE_ATTRIBUTE_NAME</code> ("vid") and if not
 * supplied the <code>ReportTypes.EXECUTIVE_OVERVIEW</code> report type will
 * be used.</li>
 * <li><code>JAnalytics.LIMIT_ATTRIBUTE_NAME</code> ("ns") and if not
 * supplied the <code>JAnalytics.DEFAULT_MAX_LIMIT</code> will be used.</li>
 * <li><code>JAnalytics.FILTER_ATTRIBUTE_NAME</code> ("fd") and if not
 * supplied an empty string will be used.</li>
 * <li><code>JAnalytics.FILTER_MODE_ATTRIBUTE_NAME</code> ("ft") and if not
 * supplied <code>FilterModes.DONT_MATCH</code> will be used</li>
 * <li>If you would like to use your own date format then you may override the
 * default format with the optional parameter given by
 * <code>JAnalytics.DATE_FORMAT_ATTRIBUTE_NAME</code> ("dateFormat").</li>
 * </ul>
 * 
 * @author Dan Andrews
 */
public class ReportServlet extends HttpServlet {

	/** Generated serialVersionUID */
	private static final long serialVersionUID = -4322994698119233193L;

	/**
	 * Process the post and if successful write the xml report to the
	 * <code>OutputStream</code>.
	 * 
	 * @param response
	 *            The <code>HttpServletResponse</code> response object.
	 * 
	 * @param request
	 *            The <code>HttpServletRequest</code> request object.
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processGetOrPost(request, response);
	}

	/**
	 * Process the get and if successful write the xml report to the
	 * <code>OutputStream</code>.
	 * 
	 * @param response
	 *            The <code>HttpServletResponse</code> response object.
	 * 
	 * @param request
	 *            The <code>HttpServletRequest</code> request object.
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processGetOrPost(request, response);
	}

	/**
	 * Process the get or post and if successful write the xml report to the
	 * <code>OutputStream</code>.
	 * 
	 * @param response
	 *            The <code>HttpServletResponse</code> response object.
	 * 
	 * @param request
	 *            The <code>HttpServletRequest</code> request object.
	 * @throws ServletException
	 * @throws IOException
	 */
	private void processGetOrPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String email = ServletUtilities.getParameterByName(request,
				JAnalytics.EMAIL_ATTRIBUTE_NAME, true);
		String password = ServletUtilities.getParameterByName(request,
				JAnalytics.PASSWORD_ATTRIBUTE_NAME, true);
		String userDateFormat = ServletUtilities.getParameterByName(request,
				JAnalytics.DATE_FORMAT_ATTRIBUTE_NAME,
				JAnalytics.DEFAULT_USER_DATE_FORMAT);
		Calendar startTime = ServletUtilities.getCalendar(ServletUtilities
				.getParameterByName(request,
						JAnalytics.START_DATE_ATTRIBUTE_NAME, true),
				userDateFormat);
		Calendar endTime = ServletUtilities.getCalendar(ServletUtilities
				.getParameterByName(request,
						JAnalytics.END_DATE_ATTRIBUTE_NAME, true),
				userDateFormat);
		String reportId = ServletUtilities.getParameterByName(request,
				JAnalytics.REPORT_ID_ATTRIBUTE_NAME, false);
		ReportTypes reportType = null;
		try {
			reportType = ReportTypes.fromInt(Integer.parseInt(ServletUtilities
					.getParameterByName(request,
							JAnalytics.REPORT_TYPE_ATTRIBUTE_NAME,
							ReportTypes.DASHBOARD_REPORT.getValueAsString())));

			// TODO: Andrew Kerr indicated that limit is not being used any
			// more, so this might be broken.

			// int limit = ServletUtilities.getIntegerParameterByName(request,
			// JAnalytics.LIMIT_ATTRIBUTE_NAME,
			// JAnalytics.DEFAULT_MAX_LIMIT);
			// if (limit <= 0) {
			// throw new ServletException(JAnalytics.LIMIT_ATTRIBUTE_NAME
			// + " may be defind in as a request parameter or "
			// + "a session attribute. This parameter is optional "
			// + "but when used must be greater than zero.");
			// }
			String filter = ServletUtilities.getParameterByName(request,
					JAnalytics.FILTER_ATTRIBUTE_NAME, "");
			FilterModes filterMode = null;
			filterMode = FilterModes.fromInt(ServletUtilities
					.getIntegerParameterByName(request,
							JAnalytics.FILTER_MODE_ATTRIBUTE_NAME,
							FilterModes._DONT_MATCH));

			response.setHeader("Content-Type", "text/xml");

			// Utilities will automatically use cache if configured
			response.getOutputStream().print(
					Utilities.getDocumentAsString(email, password, reportId,
							reportType, startTime, endTime, filter, filterMode,
							1000));

		} catch (JAnalyticsException e) {
			throw new ServletException(e.getMessage(), e);
		} catch (IllegalArgumentException e) {
			throw new ServletException(e.getMessage(), e);
		}
	}

}
